package gov.fgn.sijyp.general.util.security;

import gov.fgn.siijt.core.context.ISessionContext;
import gov.fgn.sijyp.general.data.Permisos;

import java.io.Serializable;
import java.security.Principal;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;

/**
 * Esta clase es necesaria para el manejo de parámetros nulos desde interfaces de usuario que usan
 * expression language.
 * 
 * @author leonardo.contreras
 */
@Named("permissionAdapter")
@SessionScoped
public class PermissionAdapter implements Serializable {

  private static final long serialVersionUID = -8249755794463128618L;
  private Set<String> principals;
  
  @PersistenceContext(unitName="default")
  private EntityManager em;
  @Inject
  private ISessionContext ctx;

  public PermissionAdapter() {
	  principals = new HashSet<String>();
  }
  
  public List<Permisos> getAllPermissionsForPrincipal(Object resource) {
	  Principal principal = ctx.getPrincipal();
    if (principal != null) {
      String queryString = "select p from Permisos p where p.principal in :principals and recurso like :recurso";
      TypedQuery<Permisos> queryPermissions = em.createQuery(queryString, Permisos.class);
      queryPermissions.setParameter("recurso", "%" + resource + "%");
      queryPermissions.setParameter("principals", principals);
      List<Permisos> permisos = queryPermissions.getResultList();
      return permisos;
    }
    return null;
  }

  public boolean hasPermissionUnrestricted(Object resource, String permission) {
    String queryString = "select p from Permisos p where p.principal in :principals and recurso like :recurso";
    TypedQuery<Permisos> queryPermissions = em.createQuery(queryString, Permisos.class);
    queryPermissions.setParameter("recurso", "%" + resource + "%");
    queryPermissions.setParameter("principals", principals);

    List<Permisos> permisos = queryPermissions.getResultList();
    if (permisos != null && permisos.size() > 0) {
      if ("".equals(permission) | permission == null)
        return false;
      else {
        for (Permisos per : permisos) {
          if (per.getPermiso() == null)
            return true;
          if (per.getPermiso().equals(permission)) {
            if (per.getExcepto() == null || per.getExcepto().equals(""))
              return true;
          }
        }
        return false;
      }

    }
    return false;
  }

  public String getPermissionExcept(Object resource, String permission) {
    String except = "";
    String queryString = "select p from Permisos p where p.principal in :principals and recurso like :recurso and permiso = :permission";
    TypedQuery<Permisos> queryPermissions = em.createQuery(queryString, Permisos.class);
    queryPermissions.setParameter("recurso", "%" + resource + "%");
    queryPermissions.setParameter("principals", principals);
    queryPermissions.setParameter("permission", permission);

    List<Permisos> permisos = queryPermissions.getResultList();

    if (permisos != null) {
      if (!permisos.isEmpty()) {
        Permisos p = permisos.get(0);
        except = p.getExcepto();
      }
    }

    return except;
  }

  public void loadAvailablePrincipals() {
    List<String> principals = getAvailablePrincipals();
    for(String principal : principals) {
    	if(ctx.isUserInRole(principal)) {
    		this.principals.add(principal);
    	}
    }
    this.principals.add(ctx.getPrincipal().getName());
  } 
  
  	@Deprecated
  public List<String> getAvailablePrincipals() {
    String queryString = "select distinct p.principal from Permisos p";
    TypedQuery<String> queryPrincipals = em.createQuery(queryString, String.class);
    List<String> principals = queryPrincipals.getResultList();
    return principals;
  }

}
